// draggableScrollMixin.js

// 引入节流函数
import throttle from "lodash.throttle";

/**
 * 为 vxe-table 提供鼠标拖拽横向滚动功能的 Vue Mixin
 * 使用方法:
 * 1. 在组件中引入并混入: mixins: [draggableScrollMixin]
 * 2. 确保 vxe-table 的 ref 为 'xTable'
 * 3. 确保包含表格的容器 ref 为 'tableContainer'
 * 4. 在组件的 mounted 钩子中调用 setupDraggableScroll()
 * 5. 在组件的 beforeDestroy 钩子中调用 teardownDraggableScroll()
 */
export const draggableScrollMixin = {
    data() {
        return {
            // 拖拽状态
            isDragging: false,
            startX: 0,
            startXScrollLeft: 0,
            // 存储节流后的滚动函数
            _throttledScrollTo: null,
        };
    },
    methods: {
        /**
         * 初始化拖拽滚动功能
         * 需要在组件 mounted 后调用
         */
        setupDraggableScroll() {
            if (!this.$refs.xTable || !this.$refs.tableContainer) {
                console.warn('draggableScrollMixin: 未找到必要的 refs (xTable 或 tableContainer)');
                return;
            }

            // 创建节流函数，限制为每 16ms (约 60fps) 执行一次
            this._throttledScrollTo = throttle(this._performScroll, 16, {
                leading: true,
                trailing: true,
            });

            // 设置初始鼠标样式
            this.$refs.tableContainer.style.cursor = "grab";

            // 绑定全局事件监听器
            this._setupGlobalEventListeners();
        },

        /**
         * 清理拖拽滚动功能
         * 建议在组件 beforeDestroy 前调用
         */
        teardownDraggableScroll() {
            this._handleMouseUp(); // 确保状态清理
            if (this._throttledScrollTo && this._throttledScrollTo.cancel) {
                this._throttledScrollTo.cancel();
            }
            this._removeGlobalEventListeners();
        },

        // --- 内部方法 (以下划线开头) ---

        /**
         * 鼠标按下事件处理
         */
        _handleMouseDown(event) {
            if (event.button !== 0) return; // 仅响应左键

            this.isDragging = true;
            this.startX = event.clientX;
            // 获取拖拽开始时的水平滚动位置
            const scrollInfo = this.$refs.xTable.getScroll();
            this.startXScrollLeft = scrollInfo.scrollLeft || 0;

            // 防止拖拽时选中文本
            document.body.style.userSelect = "none";
            document.body.style.webkitUserSelect = "none"; // 兼容 Safari
            // 设置鼠标样式为抓取中
            if (this.$refs.tableContainer) {
                this.$refs.tableContainer.style.cursor = "grabbing";
            }
            event.preventDefault(); // 防止默认拖拽行为
        },

        /**
         * 鼠标移动事件处理 (原始监听器)
         */
        _handleMouseMove(event) {
            if (!this.isDragging) return;

            // 通过节流函数调用实际滚动逻辑
            if (this._throttledScrollTo) {
                this._throttledScrollTo(event);
            }
        },

        /**
         * 实际执行滚动的函数 (被节流)
         */
        _performScroll(event) {
            if (!this.isDragging || !this.$refs.xTable) return; // 再次检查状态和引用

            const deltaX = event.clientX - this.startX;
            // 计算新的目标水平滚动位置 (注意方向)
            const targetScrollLeft = this.startXScrollLeft - deltaX;

            // 获取当前垂直滚动位置，以保持不变
            const currentScrollTop = this.$refs.xTable.getScroll().scrollTop || 0;

            // 调用 vxe-table 的 scrollTo 方法
            this.$refs.xTable.scrollTo(targetScrollLeft, currentScrollTop);
        },

        /**
         * 鼠标释放/离开事件处理
         */
        _handleMouseUp() {
            if (this.isDragging) {
                this.isDragging = false;
                // 恢复文本选择
                document.body.style.userSelect = "";
                document.body.style.webkitUserSelect = "";
                // 恢复鼠标样式
                if (this.$refs.tableContainer) {
                    this.$refs.tableContainer.style.cursor = "grab";
                }
            }
        },

        /**
         * 绑定全局事件监听器
         */
        _setupGlobalEventListeners() {
            document.addEventListener("mousemove", this._handleMouseMove);
            document.addEventListener("mouseup", this._handleMouseUp);
            // 如果需要在鼠标离开容器时也停止拖拽，可以添加
            // this.$refs.tableContainer?.addEventListener('mouseleave', this._handleMouseUp);
        },

        /**
         * 移除全局事件监听器
         */
        _removeGlobalEventListeners() {
            document.removeEventListener("mousemove", this._handleMouseMove);
            document.removeEventListener("mouseup", this._handleMouseUp);
            // this.$refs.tableContainer?.removeEventListener('mouseleave', this._handleMouseUp);
        },
    },
};




